package com.youlu.campus.activity.service.impl;

import com.youlu.campus.activity.entity.ActivityLotteryConfig;
import com.youlu.campus.activity.entity.ActivityLotteryConfigPrize;
import com.youlu.campus.activity.entity.ActivityLotteryConfigPrizeVo;
import com.youlu.campus.activity.entity.ActivityLotteryConfigVo;
import com.youlu.campus.activity.entity.ActivityLotteryPrize;
import com.youlu.campus.activity.entity.ActivityLotteryVo;
import com.youlu.campus.activity.repositories.ActivityLotteryConfigRepository;
import com.youlu.campus.activity.service.ActivityInfoService;
import com.youlu.campus.activity.service.ActivityLotteryConfigPrizeService;
import com.youlu.campus.activity.service.ActivityLotteryConfigService;
import com.youlu.campus.activity.service.ActivityLotteryPrizeService;
import com.youlu.campus.activity.service.ActivityTaskInfoService;
import com.youlu.campus.common.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.enums.TaskBizType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 抽奖配置服务接口
 */
@Slf4j
@Service
public class ActivityLotteryConfigServiceImpl implements ActivityLotteryConfigService {


    @Autowired
    private ActivityLotteryConfigRepository activityLotteryConfigRepository;

    @Autowired
    private ActivityLotteryPrizeService activityLotteryPrizeService;

    @Autowired
    private ActivityLotteryConfigPrizeService activityLotteryConfigPrizeService;

    @Lazy
    @Autowired
    private ActivityInfoService activityInfoService;

    @Lazy
    @Autowired
    private ActivityTaskInfoService activityTaskInfoService;

    @Override
    public ActivityLotteryConfig findByActivityId(String activityId) {
        return activityLotteryConfigRepository.findByActivityId(activityId);
    }

    @Override
    public ActivityLotteryConfigVo info(String activityId) {
        ActivityLotteryConfig activityLotteryConfig = activityLotteryConfigRepository.findByActivityId(activityId);
        if (Objects.isNull(activityLotteryConfig)) {
            return null;
        }
        ActivityLotteryConfigVo activityLotteryConfigVo = new ActivityLotteryConfigVo();
        BeanUtils.copyProperties(activityLotteryConfig, activityLotteryConfigVo);
        List<ActivityLotteryConfigPrize> configPrizes = activityLotteryConfigPrizeService.findByLotteryId(activityLotteryConfig.getId());
        activityLotteryConfigVo.setPrizes(configPrizes);
        return activityLotteryConfigVo;
    }

    @Override
    public ActivityLotteryVo infoByEnable(String activityId) {
        ActivityLotteryConfig activityLotteryConfig = activityLotteryConfigRepository.findByActivityIdAndStatus(activityId, 1);
        if (Objects.isNull(activityLotteryConfig)) {
            throw new BusinessException("抽奖活动未开启");
        }
        ActivityLotteryVo activityLotteryVo = new ActivityLotteryVo();
        BeanUtils.copyProperties(activityLotteryConfig, activityLotteryVo);

        List<ActivityLotteryConfigPrize> configPrizes = activityLotteryConfigPrizeService.findByLotteryId(activityLotteryConfig.getId());
        if (Objects.isNull(configPrizes)) {
            throw new BusinessException("活动奖品不存在");
        }
        //转换奖品vo
        List<ActivityLotteryConfigPrizeVo> prizes = configPrizes.stream().map(
                configPrize -> {
                    return getActivityLotteryConfigPrizeVo(configPrize);
                }
        ).sorted(Comparator.comparingInt(ActivityLotteryConfigPrizeVo::getSort)).collect(Collectors.toList());
        activityLotteryVo.setPrizes(prizes);
        return activityLotteryVo;
    }

    /**
     * 获取 奖品vo
     *
     * @param configPrize
     * @return
     */
    private ActivityLotteryConfigPrizeVo getActivityLotteryConfigPrizeVo(ActivityLotteryConfigPrize configPrize) {
        ActivityLotteryPrize prize = activityLotteryPrizeService.findById(configPrize.getPrizeId());
        ActivityLotteryConfigPrizeVo activityLotteryConfigPrizeVo = new ActivityLotteryConfigPrizeVo();
        activityLotteryConfigPrizeVo.setOneCount(configPrize.getOneCount());
        activityLotteryConfigPrizeVo.setTotalCount(configPrize.getTotalCount());
        activityLotteryConfigPrizeVo.setRemainingCount(configPrize.getRemainingCount());
        activityLotteryConfigPrizeVo.setProbability(configPrize.getProbability());
        activityLotteryConfigPrizeVo.setSort(configPrize.getSort());
        activityLotteryConfigPrizeVo.setConfigPrizeId(configPrize.getId());

        activityLotteryConfigPrizeVo.setId(prize.getId());
        activityLotteryConfigPrizeVo.setPrizeName(prize.getPrizeName());
        activityLotteryConfigPrizeVo.setPrizeImg(prize.getPrizeImg());
        activityLotteryConfigPrizeVo.setPrizeType(prize.getPrizeType());
        activityLotteryConfigPrizeVo.setDescription(prize.getDescription());
        activityLotteryConfigPrizeVo.setLotteryId(configPrize.getLotteryId());
        return activityLotteryConfigPrizeVo;
    }

    @Override
    public ActivityLotteryConfigVo save(ActivityLotteryConfigVo config) {
        log.info("save param config:{}", config);
        ActivityInfo activityInfo = activityInfoService.findById(config.getActivityId());
        if (activityInfo == null) {
            throw new BusinessException("活动不存在");
        }
        for (ActivityLotteryConfigPrize prize : config.getPrizes()) {
            if (prize.getTotalCount() < prize.getOneCount()) {
                throw new BusinessException("奖品总数量必须大于获奖数量");
            }
        }
        ActivityLotteryConfig activityLotteryConfig = activityLotteryConfigRepository.findByActivityId(config.getActivityId());
        if (activityLotteryConfig == null) {
            activityLotteryConfig = new ActivityLotteryConfig();
            activityLotteryConfig.setCreateTime(LocalDateTime.now());
        } else {
            activityLotteryConfig.setUpdateTime(LocalDateTime.now());
        }
        //抽奖配置
        activityLotteryConfig.setActivityId(config.getActivityId());
        activityLotteryConfig.setDailyDrawLimit(config.getDailyDrawLimit());
        activityLotteryConfig.setPoints(config.getPoints());
        activityLotteryConfig.setStatus(config.getStatus());
        activityLotteryConfig.setPointsAlias(activityInfo.getRewardValueAlias());
        activityLotteryConfig.setGiftNums(config.getGiftNums());
        activityLotteryConfig.setCustomerService(config.getCustomerService());

        //查询邀请任务
        ActivityTaskInfo taskInfo = activityTaskInfoService.findActivityTaskInfo(config.getActivityId(), TaskBizType.INVITE);
        if (Objects.nonNull(taskInfo)) {
            activityLotteryConfig.setTaskId(taskInfo.getId());
            activityLotteryConfig.setInvitePoints(taskInfo.getPoints().intValue());
        }
        activityLotteryConfig = activityLotteryConfigRepository.save(activityLotteryConfig);
        //奖品配置
        if (CollectionUtils.isNotEmpty(config.getPrizes())) {
            for (ActivityLotteryConfigPrize prize : config.getPrizes()) {
                prize.setLotteryId(activityLotteryConfig.getId());
                prize.setRemainingCount(prize.getTotalCount());
            }
            activityLotteryConfigPrizeService.batchSaveByLotteryId(activityLotteryConfig.getId(), config.getPrizes());
        }
        config.setId(activityLotteryConfig.getId());

        //设置活动 是否支持抽奖
        activityInfo.setEnableLottery(config.getStatus() == 1);
        activityInfoService.save(activityInfo);
        log.info("save result config:{}", config);
        return config;
    }

    @Async
    @Override
    public void updateInvitePoints(String activityId) {
        log.info("updateInvitePoints 更新抽奖活动邀请赠送贡献值 activityId:{}", activityId);
        ActivityLotteryConfig activityLotteryConfig = activityLotteryConfigRepository.findByActivityId(activityId);
        if (Objects.isNull(activityLotteryConfig)) {
            log.info("updateInvitePoints 抽奖活动不存在 activityId:{}", activityId);
            return;
        }
        //查询邀请任务
        ActivityTaskInfo taskInfo = activityTaskInfoService.findActivityTaskInfo(activityId, TaskBizType.INVITE);
        if (Objects.nonNull(taskInfo)) {
            int points = taskInfo.getPoints().intValue();
            if (points == activityLotteryConfig.getInvitePoints()) {
                log.info("updateInvitePoints 邀请活动贡献值相同 activityId:{},points:{},InvitePoints:{}", activityId, points, activityLotteryConfig.getInvitePoints());
                return;
            }
            activityLotteryConfig.setInvitePoints(taskInfo.getPoints().intValue());
            activityLotteryConfig.setTaskId(taskInfo.getId());
        } else {
            activityLotteryConfig.setTaskId(null);
            activityLotteryConfig.setInvitePoints(0);
        }
        log.info("updateInvitePoints taskId:{},points:{}", activityLotteryConfig.getTaskId(), activityLotteryConfig.getInvitePoints());
        activityLotteryConfigRepository.save(activityLotteryConfig);
    }

    @Async
    @Override
    public void updatePointsAlias(String activityId) {
        log.info("updatePointsAlias 更新抽奖活动贡献值别名 activityId:{}", activityId);
        ActivityLotteryConfig activityLotteryConfig = activityLotteryConfigRepository.findByActivityId(activityId);
        if (Objects.isNull(activityLotteryConfig)) {
            log.info("updatePointsAlias 抽奖活动不存在 activityId:{}", activityId);
            return;
        }
        ActivityInfo activityInfo = activityInfoService.findById(activityId);
        if (activityInfo.getRewardValueAlias().equals(activityLotteryConfig.getPointsAlias())) {
            return;
        }
        activityLotteryConfig.setPointsAlias(activityInfo.getRewardValueAlias());
        log.info("updatePointsAlias PointsAlias:{}", activityLotteryConfig.getPointsAlias());
        activityLotteryConfigRepository.save(activityLotteryConfig);
    }

    @Override
    public boolean delete(String id) {
        log.info("delete param id:{}", id);
        activityLotteryConfigRepository.deleteById(id);
        return true;
    }

}
